
#include "board.h"

Board board;
/*----------------device bus handle-----------------*/
static lcd_spi_bus_handle_t lcd_handle;
static gpio_out_bus_handle_t gpio_led_handle[1];
static sc8701_bus_handle_t sc8701_handle;
static gpio_key_bus_handle_t key_handle[BOARD_KEY_NUM];
static pwm_out_bus_handle_t pwm_led_handle[2];
static pwm_out_bus_handle_t buzzer_handle;
static i2c_simulate_bus_handle_t i2c_bus_handle;
static i2c_simulate_bus_handle_t fusb302_bus_handle;

//extern void usb_usart_config( linecoding_type *linecoding);
extern void usb_clock48m_select(usb_clk48_s clk_s);

/*
uint8_t uartBuffer0[512], uartBuffer1[512];
board_uart_config_t uart_config[BOARD_UART_NUM] = {
    {.buffer=uartBuffer0, .buffer_size=512, .baudrate=9600, .parity=kUART_ParityDisabled, },
    {.buffer=uartBuffer1, .buffer_size=512, .baudrate=9600, .parity=kUART_ParityDisabled, },
};
*/

void board_rtos_init(void)
{
    /* add semaphores, ... */
}

void board_get_uid_6(uint8_t *id)
{
	const uint8_t *p = (const uint8_t *)0x1FFFF7E8;
	memcpy(id, p, 6);
}

void board_usb_config(void)
{
/*    board.cdc.linecoding.bitrate = 115200;
    board.cdc.linecoding.format = 0;
    board.cdc.linecoding.parity = 0;
    board.cdc.linecoding.data = 8;
*/
    /* hardware usart config: usart1 */
    //usb_usart_config(&board.cdc.linecoding);
    /* select usb 48m clcok source */
    usb_clock48m_select(USB_CLK_HICK);
    /* enable usb clock */
    crm_periph_clock_enable(CRM_USB_PERIPH_CLOCK, TRUE);
    /* enable usb interrupt */
    nvic_irq_enable(USBFS_L_CAN1_RX0_IRQn, 0, 0);
    /* usb core init */
    //usb_dev_init(USB);
    /* enable usb pull-up */
    //usb_connect(USB);
}

void usb_dc_low_level_init(void)
{
    board_usb_config();
}

void board_init(void)
{
    uint16_t i;
    
    //board_usb_config();
    
    lcd_handle.dc.port = hal_port(PB, 14);
    lcd_handle.rst.port = hal_port(PC, 6);
    lcd_handle.cs.port = hal_port(PB, 12);
    lcd_handle.spi_base = SPI2_BASE;
    lcd_handle.dma_base = DMA1_CHANNEL2_BASE;
    
    hal_pin_set(&lcd_handle.dc);
    hal_pin_set(&lcd_handle.cs);
    
    dev_connect(&board.lcd_dev, &lcd_handle, &lcd_spi_bus);
    lcd_154hsc04a_init(&board.lcd_dev);
  
    gpio_led_handle[0].io.port = hal_port(PC, 4);
    dev_connect(&board.led[kBoardLed_Alarm], &gpio_led_handle[0], &gpio_out_bus);
    led_init(&board.led[kBoardLed_Alarm], 200, 0, 0);
    led_on(&board.led[kBoardLed_Alarm]);
 
    pwm_led_handle[0].pwm.port = hal_port(T1, 1);
    dev_connect(&board.lcd_backlight, &pwm_led_handle[0], &pwm_out_bus);
    led_init(&board.lcd_backlight, 20, 0, MHZ(10));
    
    pwm_led_handle[1].pwm.port = hal_port(T3, 2);
    dev_connect(&board.led[kBoardLed_Work], &pwm_led_handle[1], &pwm_out_bus);
    led_init(&board.led[kBoardLed_Work], 200, 1, MHZ(4));
    
    buzzer_handle.pwm.port = hal_port(T3, 3);
    dev_connect(&board.buzzer, &buzzer_handle, &pwm_out_bus);
    buzzer_init(&board.buzzer, MHZ(4));
    
    hal_gpio_t input_io[] = {
    {.group=PC, .ch=1}, {.group=PC, .ch=15}, {.group=PC, .ch=14}, {.group=PC, .ch=12}, {.group=PC, .ch=2}, };
    for(i=0;i!=BOARD_KEY_NUM;i++) {
        key_handle[i].io.port = input_io[i].port;
        dev_connect(&board.key[i], &key_handle[i], &gpio_key_bus);
        key_init(&board.key[i], 20, kKeyValidLevel_Low);
    }
    key_init(&board.key[kBoardKey_next], 20, kKeyValidLevel_High);
    
    sc8701_handle.cs.port = hal_port(PC, 7);
    sc8701_handle.pwm_i.pwm.port = hal_port(T8, 3);
    sc8701_handle.pwm_u.pwm.port = hal_port(T8, 4);
    dev_connect(&board.sc8701, &sc8701_handle, &sc8701_bus);
    
    i2c_bus_handle.scl.port = hal_port(PB, 10);
    i2c_bus_handle.sda.port = hal_port(PB, 11);
    
    dev_connect(&board.ina226_in, &i2c_bus_handle, &i2c_simulate_bus);
    dev_connect(&board.ina226_out, &i2c_bus_handle, &i2c_simulate_bus);
    
    INA226_init_config_t ina226_config;
    ina226_config.slave_addr = 0x45;
    ina226_config.average = INA226_AVG_16;
    ina226_config.mode = INA226_MODE_ShunBusVlotageContinuous;
    ina226_config.bus_conversion_time = INA226_CT_1100us;
    ina226_config.shut_conversion_time = INA226_CT_1100us;
    ina226_init(&board.ina226_in, &ina226_config);
    ina226_set_calibrate(&board.ina226_in, 0.005, 10);
    
    ina226_config.slave_addr = 0x40;
    ina226_init(&board.ina226_out, &ina226_config);
    ina226_set_calibrate(&board.ina226_out, 0.005, 10);
    //ina226_set_calibrate(&board.ina226_out, 0.00636, 10);
    
    fusb302_bus_handle.scl.port = hal_port(PA, 1);
    fusb302_bus_handle.sda.port = hal_port(PA, 0);
    
    dev_connect(&board.fusb302, &fusb302_bus_handle, &i2c_simulate_bus);
    //FUSB302_init(&board.fusb302);
    
    //board.serial[0].base = USART1;
    //board_uart_init(0, &uart_config[0]);
    
    //hal_hw_pin_set(GPIOA, GPIO_PINS_0);
    //hal_hw_pin_reset(GPIOA, GPIO_PINS_0);
    
}

/* 定时扫描开关按键组 */
void BoardSwitchGroupScan(uint16_t ms)
{

    
}

/* 定时节拍任务函数，在定时中断中执行 */
void BoardTimerTask(uint16_t ms)
{
    //BoardSwitchGroupScan(ms);
}

uint16_t board_get_adc(uint8_t ch)
{
    uint8_t i;
    uint32_t adc = 0;
    return adc_buff[ch];
}

int board_serial_send(uint8_t id, uint8_t *buffer, uint32_t length)
{
    while(length--) {
        while(usart_flag_get(USART1, USART_TDBE_FLAG) == RESET);
        usart_data_transmit(USART1, *buffer);
        buffer++;
    }
	return 0;
}

#define ADC_VREF                         (3.28)
#define ADC_TEMP_BASE                    (1.26)
#define ADC_TEMP_SLOPE                   (-0.00423)

float board_get_cpu_temp(void)
{
    return (ADC_TEMP_BASE - (double)board_get_adc(kBoardADC_CPUTemp) * ADC_VREF / 4096) / ADC_TEMP_SLOPE + 25;
}